#include "knapsack.h"
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>

// Global variables for timeout handling
static jmp_buf timeout_buf;
static volatile sig_atomic_t timeout_occurred = 0;

// Signal handler for timeout
void timeout_handler(int sig) {
    (void)sig;
    timeout_occurred = 1;
    longjmp(timeout_buf, 1);
}

// Function to log timeout
void logTimeout(int n, double capacity) {
    FILE* fp = fopen("dynamic_timeout.txt", "a");
    if (fp) {
        fprintf(fp, "物品数: %d, 背包容量: %.0f - 测试超时(>60秒)\n", n, capacity);
        fclose(fp);
    }
    printf("\n警告: 动态规划算法在物品数=%d,背包容量=%.0f时超时(>60秒)\n", n, capacity);
}

// Function to get current time in milliseconds
double getCurrentTimeMs() {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (ts.tv_sec * 1000.0 + ts.tv_nsec / 1000000.0);
}

// Function to run a single test case with timeout
void runTest(Item* items, int n, double capacity) {
    // Set up timeout handler
    struct sigaction sa;
    struct sigaction old_sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = timeout_handler;
    sigaction(SIGALRM, &sa, &old_sa);

    // Set timeout flag
    timeout_occurred = 0;

    if (setjmp(timeout_buf) == 0) {
        // Set alarm for 60 seconds
        alarm(60);
        
        double start_time = getCurrentTimeMs();
        Solution* sol = dynamicProgramming(items, n, capacity);
        double end_time = getCurrentTimeMs();
        
        // Cancel alarm
        alarm(0);
        
        double execution_time = end_time - start_time;

        printf("\n动态规划算法测试:\n");
        printf("物品数量: %d\n", n);
        printf("背包容量: %.0f\n", capacity);
        printf("执行时间: %.2f ms\n", execution_time);
        
        printSolution(sol, items, n);
        writeExecutionTime("dynamic", n, capacity, execution_time);
        
        freeSolution(sol);
    } else {
        // Timeout occurred
        alarm(0);  // Cancel alarm
        logTimeout(n, capacity);
    }

    // Restore old signal handler
    sigaction(SIGALRM, &old_sa, NULL);
}

int main() {
    // Generate pseudocode file
    writeFakeCode("dynamic");

    // Test parameters
    int item_counts[] = {1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 
                        10000, 20000, 40000, 80000, 160000, 320000};
    double capacities[] = {10000, 100000, 1000000};
    int num_item_counts = sizeof(item_counts) / sizeof(item_counts[0]);
    int num_capacities = sizeof(capacities) / sizeof(capacities[0]);

    printf("开始动态规划算法测试...\n");

    // For each capacity
    for (int c = 2; c < num_capacities; c++) {
        double capacity = capacities[c];
        printf("\n=== 测试背包容量: %.0f ===\n", capacity);

        // For each item count
        for (int i = 0; i < num_item_counts; i++) {
            int n = item_counts[i];
            printf("\n--- 测试物品数量: %d ---\n", n);
            if (n > 200000) {
                printf("\n物品数 %d (超时)\n", n);
                continue;
            }

            // Generate items
            Item* items = (Item*)malloc(n * sizeof(Item));
            generateItems(items, n);

            runTest(items, n, capacity);

            free(items);
        }
    }

    return 0;
} 